﻿using System.Collections;
using System.Collections.Generic;
using System.Data.SqlClient;
using SSAT.Utils;

namespace SSAT.ConnectionStringsManagement
{
    internal sealed class ConnectionStringsStorage : IEnumerable<KeyValuePair<string, string>>
    {
        private readonly IConnectionStringsSaver _saver;
        private IDictionary<string, string> _connectionStrings = new Dictionary<string, string>();

        public int Count
        {
            get { return _connectionStrings.Count; }
        }

        public string this[string dataSource]
        {
            get { return _connectionStrings[dataSource]; }
        }

        public ConnectionStringsStorage(IConnectionStringsSaver saver)
        {
            Verification.CheckArgumentForNull(saver, "saver");
            _saver = saver;
        }

        public ConnectionStringsStorage()
            : this(new IsolatedStorageStringsSaver())
        { }

        public void Save(string connectionString)
        {
            Verification.CheckStringForNullOrEmpty(connectionString, "connectionString");
            SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(connectionString);
            Save(builder);
        }

        public void Save(SqlConnectionStringBuilder builder)
        {
            if (string.IsNullOrEmpty(builder.DataSource))
            {
                return;
            }
            string connectionStringToSave = PrepareConnectionStringToSave(builder);
            _saver.Save(builder.DataSource, connectionStringToSave);
            _connectionStrings[builder.DataSource] = connectionStringToSave;
        }

        private static string PrepareConnectionStringToSave(SqlConnectionStringBuilder builder)
        {
            Verification.CheckArgumentForNull(builder, "builder");
            string connectionStringToSave = GetConnectionStringWithoutPassword(builder);
            Verification.CheckStringForNullOrEmpty(connectionStringToSave, "builder", Resources.ConnectionStringMustContainOtherInformationBesidesUIDandPWD);
            return connectionStringToSave;
        }

        public void Load()
        {
            _connectionStrings = _saver.Load();
        }

        private static string GetConnectionStringWithoutPassword(SqlConnectionStringBuilder builder)
        {
            SqlConnectionStringBuilder builderWithoutUidAndPwd = new SqlConnectionStringBuilder(builder.ConnectionString);
            builderWithoutUidAndPwd.Password = string.Empty;
            return builderWithoutUidAndPwd.ConnectionString;
        }

        public void Clear()
        {
            _connectionStrings.Clear();
        }

        public bool Contains(string dataSource)
        {
            return _connectionStrings.ContainsKey(dataSource);
        }

        #region IEnumerable<KeyValuePair<string,string>> Members

        IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator()
        {
            return _connectionStrings.GetEnumerator();
        }

        #endregion

        #region IEnumerable Members

        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IEnumerable<KeyValuePair<string, string>>)this).GetEnumerator();
        }

        #endregion
    }
}
